﻿using System;
using System.ComponentModel;
using System.Linq;
using Caliburn.Micro;
using Castle.Core;
using Castle.Windsor;
using Microsoft.Windows.Controls;
using TimeKeeper.ViewModels;

namespace TimeKeeper
{
    public class Bootstrapper : Bootstrapper<ShellViewModel>
    {
        WindsorContainer _container;

        protected override void Configure()
        {
            //How to handle DoubleUpDown control from wpf extension toolkit
            ConventionManager.AddElementConvention<DoubleUpDown>(DoubleUpDown.ValueProperty, "Value", "ValueChanged");

            //Force validation for entity objects because they have proxy with IDataErrorInfo
            ConventionManager.ApplyValidation = (binding, viewModelType, property) =>
            {
                if (typeof(IDataErrorInfo).IsAssignableFrom(viewModelType) 
                    || viewModelType.FullName.StartsWith("TimeKeeper.Entities"))
                {
                    binding.ValidatesOnDataErrors = true;
                }
            };

            _container = new WindsorContainer();
            _container.Install(new ContainerInstaller());
        }

        protected override object GetInstance(Type service, string key)
        {
            return string.IsNullOrWhiteSpace(key) ? _container.Resolve(service) : _container.Resolve(key, service);
        }

        protected override void BuildUp(object instance)
        {
            instance.GetType().GetProperties()
                .Where(property => property.CanWrite && property.PropertyType.IsPublic)
                .Where(property => _container.Kernel.HasComponent(property.PropertyType))
                .ForEach(property => property.SetValue(instance, _container.Resolve(property.PropertyType), null));
        }

        //protected override IEnumerable<Assembly> SelectAssemblies()
        //{
        //    //Views and viewmodels are in different assembly than entry assembly.
        //    return new[] { Assembly.GetExecutingAssembly() };
        //}

        protected override void OnExit(object sender, EventArgs e)
        {
            base.OnExit(sender, e);
            _container.Dispose();
            _container = null;
        }
    }
}
